﻿using System.Collections.Generic;
using System.Web.Mvc;
using NUnit.Framework;
using WeBlog.Controllers;
using WeBlog.DataContext;
using WeBlog.Interfaces;
using WeBlog.Models;
using WeBlog.Repositories;
using WeBlog.Tests.Helpers;

namespace WeBlog.Tests.Controllers {
	[TestFixture]
	public class CategoryControllerTests 
    {
        private IUnitOfWork _unitOfWork;

        [SetUp]
        public void Setup()
        {
            _unitOfWork = new InMemoryUnitOfWork();
            var categoryRepository = new CategoryRepository(_unitOfWork);
            var category = new Category{ CategoryId = 1, Name = "Hello World", Posts = new List<Post>() { } };
            var category2 = new Category { CategoryId = 2, Name = "Hello World2", Posts = new List<Post>() { } };
            var category3 = new Category { CategoryId = 3, Name = "Hello World3", Posts = new List<Post>() { } };
            categoryRepository.Add(category);
            categoryRepository.Add(category2);
            categoryRepository.Add(category3); 
        }

		[Test]
		public void Manage_Action_Returns_Valid_Model() 
        {
            //Arrange
            var controller = new CategoryController(_unitOfWork);
		    controller.SetFakeControllerContext();

            //Act
            var result = controller.Manage(new GridSettings("Name")) as ViewResult;

            //Assert
            Assert.IsNotNull(result.ViewData.Model);
            Assert.IsInstanceOf(typeof(ManageCategoriesViewModel), result.ViewData.Model);			
		}

		[Test]
		public void Details_Action_Returns_Valid_Model() 
        {
            //Arrange
            var controller = new CategoryController(_unitOfWork);

            //Act
            var result = controller.Details(new GridSettings("Name"), "Hello World") as ViewResult;
            
            //Assert
            Assert.IsNotNull(result.ViewData.Model);
            Assert.IsInstanceOf( typeof(CategoryDetailsViewModel), result.ViewData.Model);			
		}

        /*[Test]
        public void Details_Returns_NotFound_For_Invalid_Category()
        {
            //Arrange
            var controller = new CategoryController(_unitOfWork);
            
            //Act
            //var result = controller.Details("the category does not exist") as ViewResult;
            
            //Assert
            //Assert.AreEqual("NotFound", result.ViewName);
        }*/

        [Test]
        public void Create_Action_Should_Insert_Data()
        {
            //Arrange
            var controller = new CategoryController(_unitOfWork);

            //Act
            var result = controller.Create("TestCategory", "TestDescription") as JsonResult;

            //Assert
            var id = ((result.Data as JsonResponse).Result as Category).CategoryId;
            Assert.IsTrue((result.Data as JsonResponse).Success);
            Assert.IsNotNull(new CategoryRepository(_unitOfWork).FindById(id));
            Assert.AreEqual("TestCategory", new CategoryRepository(_unitOfWork).FindById(id).Name);
            Assert.AreEqual("TestDescription", new CategoryRepository(_unitOfWork).FindById(id).Description);
        }

        [Test]
        public void Create_Action_Should_Fail_When_UnitOfWork_Is_Null()
        {
            //Arrange           
            var controller = new CategoryController(null);

            //Act
            var result = controller.Create("category1", "description1") as JsonResult;

            //Assert
            Assert.IsFalse((result.Data as JsonResponse).Success);
        }

        [Test]
        public void Delete_Action_Should_Remove_Data()
        {
            //Arrange
            var controller = new CategoryController(_unitOfWork);

            //Act
            var result = controller.Delete(3) as JsonResult;

            //Assert
            Assert.IsTrue((result.Data as JsonResponse).Success);
            Assert.IsNull(new CategoryRepository(_unitOfWork).FindById(3));
        }

        [Test]
        public void Delete_Action_Should_Fail_When_CategoryId_Is_Invalid()
        {
            //Arrange
            var controller = new CategoryController(_unitOfWork);

            //Act
            var result = controller.Delete(100) as JsonResult;

            //Assert
            Assert.IsFalse((result.Data as JsonResponse).Success);
        }

        [Test]
        public void Edit_Action_Should_Update_Data()
        {
            //Arrange
            var controller = new CategoryController(_unitOfWork);

            //Act
            var result = controller.Edit(2, "MyCategory", "MyDescription") as JsonResult;

            //Assert
            Assert.IsTrue((result.Data as JsonResponse).Success);
            Assert.AreEqual("MyCategory", new CategoryRepository(_unitOfWork).FindById(2).Name);
            Assert.AreEqual("MyDescription", new CategoryRepository(_unitOfWork).FindById(2).Description);
        }

        [Test]
        public void Edit_Action_Should_Fail_When_CategoryId_Is_Invalid()
        {
            //Arrange
            var controller = new CategoryController(_unitOfWork);

            //Act
            var result = controller.Edit(100, "MyCategory", "MyDescription") as JsonResult;

            //Assert
            Assert.IsFalse((result.Data as JsonResponse).Success);
        }
    }
}
